from rest_framework import serializers
from rest_framework_jwt.settings import api_settings
from django_redis import get_redis_connection

from django.contrib.auth.hashers import make_password
from . import models

import re


# 此序列化器用于用户的注册。
# 主要涉及的字段：手机号码，密码，验证码，用户id，用户名，JWT密文。
class UserModelSerializer(serializers.ModelSerializer):

    # 增加额外字段
    sms_code = serializers.CharField(required=True, help_text='短信验证码', write_only=True, label='验证码')
    token = serializers.CharField(help_text='token认证字符串', read_only=True)

    class Meta:
        model = models.User
        fields = ['mobile', 'password', 'sms_code', 'id', 'username', 'token']
        extra_kwargs = {
            'id': {
                'read_only': True,
            },
            'username': {
                'read_only': True,
            },
            'mobile': {
                'write_only': True,
            },
            'password': {
                'write_only': True,
            }
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in self.fields:
            if self.fields[field].label:
                print(self.fields[field].error_messages)
                self.fields[field].error_messages['blank'] = self.fields[field].label + '不能为空！'
                print(self.fields[field].error_messages)
            # error_messages 显示所有字段的错误提示信息
            # print(self.fields[field].error_messages)

    # 全局钩子
    def validate(self, attrs):
        mobile = attrs.get('mobile')
        sms_code = attrs.get('sms_code')

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            raise serializers.ValidationError('对不起，手机号码格式错误')

        if models.User.objects.filter(mobile=mobile):
            raise serializers.ValidationError('该手机号码已被注册！！')

        # 验证手机验证码是否正确
        redis_conn = get_redis_connection('sms_code')
        redis_sms_code = redis_conn.get(f'sms_{mobile}').decode()
        # print(sms_code, redis_sms_code)
        if sms_code != redis_sms_code:
            raise serializers.ValidationError('验证码输入有误')
        return attrs

    def create(self, validated_data):

        # 新建的用户名唯一
        validated_data['username'] = validated_data['mobile']
        # 密文形式的密码
        validated_data['password'] = make_password(validated_data['password'])

        # 删除sms_code字段，不能写入数据库
        del validated_data['sms_code']

        user = models.User.objects.create(**validated_data)

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        # user 校验成功后返回的 model 对象中添加token:'密文'键值对
        user.token = token

        return user


# 此序列化器用于完善个人信息
class PerfectInformationModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.User
        fields = [
            'avatar',
            'sex',
            'birthday',
            'receipt_address',
            'signature',
            'WeChat',
            'OICQ',
            'professional',
            'hobbies',
            'mobile',
            'username',
            'email',
            'learning_experience',
        ]

        extra_kwargs = {
            'avatar': {
                'read_only': True
            }
        }


# 此序列化器用来重置密码
class ResetPasswordModelSerializer(serializers.ModelSerializer):

    email_code = serializers.CharField(required=True, help_text='邮箱验证码', write_only=True, label='邮箱验证码')

    class Meta:
        model = models.User
        fields = ['id', 'username', 'password', 'email_code', 'email']

        extra_kwargs = {
            'id': {
                'read_only': True
            },
            'username': {
                'read_only': True
            },
            'password': {
                'write_only': True
            },
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in self.fields:
            if self.fields[field].label:
                print(self.fields[field].error_messages)
                self.fields[field].error_messages['blank'] = self.fields[field].label + '不能为空！'
                print(self.fields[field].error_messages)

    def validate(self, attrs):

        email = attrs.get('email')
        email_code = attrs.get('email_code')
        print(email_code)

        # 验证手机验证码是否正确
        redis_conn = get_redis_connection('email_code')
        print(email)
        print(redis_conn.get(f'email_code_{email}'))
        redis_email_code = redis_conn.get(f'email_code_{email}').decode()
        if email_code != redis_email_code:
            raise serializers.ValidationError('验证码输入有误')
        return attrs

    def update(self, instance, validated_data):

        instance.password = make_password(validated_data['password'])
        instance.save()

        return instance
